package admin

import (
	"log"
	"net"
	"net/http"
	"strings"
	"text/template"
	"time"

	"gitee.com/cxssang/goframe/lib/crypto"

	"gitee.com/cxssang/goframe/lib/sql"
	"gitee.com/cxssang/goframe/lib/utils"

	"gitee.com/cxssang/genealogy/fs"

	. "gitee.com/cxssang/genealogy/act"
)

func getLoginIp(r *http.Request) string {
	if r.Header.Get("X-Forwarded-For") != "" {
		ips := r.Header.Get("X-Forwarded-For")
		if strings.Index(ips, ",") != -1 {
			return strings.SplitN(ips, ",", 2)[0]
		}
		return strings.Split(ips, ":")[0]
	}
	remoteAddr := r.RemoteAddr
	if ip := r.Header.Get("Remote_addr"); ip != "" {
		remoteAddr = ip
	} else {
		remoteAddr, _, _ = net.SplitHostPort(remoteAddr)
	}

	if remoteAddr == "::1" {
		remoteAddr = "127.0.0.1"
	}
	return remoteAddr
}

func init() {
	HandleFunMap["/admin/login"] = func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case "GET":
			t := template.New("login")
			tf, err := fs.FS.ReadFile("admin/login.html")
			if err != nil {
				log.Fatal(err)
			}
			t, err = t.Parse(string(tf))
			if err != nil {
				log.Fatal(err)
			}
			err = t.Execute(w, nil)
			if err != nil {
				log.Fatal(err)
			}
		case "POST":
			userName := r.FormValue("user_name")
			password := r.FormValue("password")
			if userName == "" {
				DisplayError(w, "请输入用户名")
				return
			}
			if password == "" {
				DisplayError(w, "请输入密码")
				return
			}
			sq := sql.New()
			row, err := sq.Select("users", sql.NewWhere().Add("name=?", userName).Add("is_admin=1"), 0, 0, "*", "").FetchOne()
			if err != nil || row == nil {
				DisplayError(w, "用户名或密码错误")
				return
			}
			if utils.Md5(password) != row.Get("password") {
				DisplayError(w, "用户名或密码错误")
				return
			}
			aes := crypto.NewAes()
			cookieVal := aes.Encrypt(row.Get("id"), string(K))
			cookie := &http.Cookie{
				Name:     "auth-key",
				Value:    cookieVal,
				HttpOnly: true,
			}
			_, _ = sq.Update("users", sql.NewWhere().Add("id=?", row.Get("id")), map[string]interface{}{
				"login_time": utils.DateTime(time.Now().Unix(), "Y-m-d H:i:s"),
				"login_ip":   getLoginIp(r),
			}).Exec()
			http.SetCookie(w, cookie)
			http.Redirect(w, r, "/admin/#/", http.StatusFound)
		}
	}

	HandleFunMap["/admin/logOut"] = func(w http.ResponseWriter, r *http.Request) {
		cookie := &http.Cookie{
			Name:     "auth-key",
			Value:    "",
			HttpOnly: true,
		}
		http.SetCookie(w, cookie)
		http.Redirect(w, r, "/admin/login", http.StatusFound)
	}

	HandleFunMap["/admin/editPswd"] = func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case "GET":
			Display(w, r, "admin/editPswd", nil)
		case "POST":
			oldPassword := r.FormValue("old_password")
			newPassword := r.FormValue("new_password")
			confirmPassword := r.FormValue("confirm_password")
			if CheckEmpty(w, oldPassword, "请输入旧密码", newPassword, "请输入新密码", confirmPassword, "请再次输入新密码") {
				return
			}
			if newPassword != confirmPassword {
				DisplayError(w, "两次输入的新密码不一致")
				return
			}
			uid := r.Header.Get("user-id")
			if uid == "" {
				DisplayError(w, "请先登录")
				return
			}
			sq := sql.New()
			row, err := sq.Select("users", sql.NewWhere().Add("id=?", uid), 0, 0, "*", "").FetchOne()
			if err != nil || row == nil {
				DisplayError(w, "用户不存在")
				return
			}
			if utils.Md5(oldPassword) != row.Get("password") {
				DisplayError(w, "旧密码错误")
				return
			}
			_, err = sq.Update("users", sql.NewWhere().Add("id=?", uid), map[string]interface{}{
				"password": utils.Md5(newPassword),
			}).Exec()
			if err != nil {
				DisplayError(w, "修改密码失败")
			} else {
				cookie := &http.Cookie{
					Name:     "auth-key",
					Value:    "",
					HttpOnly: true,
				}
				http.SetCookie(w, cookie)
				DisplayError(w, "修改密码成功", "/admin/login")
			}
		}
	}
}
